/*
 * ==========================================================================*\
 * | $Id$
 * |*-------------------------------------------------------------------------*|
 * | Copyright (C) 2009 Virginia Tech | | This file is part of CloudSpace. | |
 * CloudSpace is free software; you can redistribute it and/or modify | it under
 * the terms of the GNU General Public License as published | by the Free
 * Software Foundation; either version 3 of the License, or | (at your option)
 * any later version. | | CloudSpace is distributed in the hope that it will be
 * useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of |
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General
 * Public License for more details. | | You should have received a copy of the
 * GNU General Public License | along with CloudSpace; if not, see
 * <http://www.gnu.org/licenses/>.
 * \*==========================================================================
 */

package cloudspace.controlpanel;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.security.core.GrantedAuthority;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.SuspendNotAllowedException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.util.GenericComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Fileupload;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listhead;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Radio;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.Tabbox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

import cloudspace.config.CloudSpaceConfiguration;
import cloudspace.security.CloudSpaceUser;
import cloudspace.security.GroupFactory;
import cloudspace.security.UserRegistry;
import cloudspace.security.permissions.GroupPermissionToken;
import cloudspace.security.permissions.PermissionToken;
import cloudspace.security.permissions.PermissionsManager;
import cloudspace.security.permissions.UserPermissionToken;
import cloudspace.ui.Dialogs;
import cloudspace.ui.EditableListitem;
import cloudspace.ui.InlineEditListener;
import cloudspace.ui.InlineEditor;
import cloudspace.ui.impl.NewUserDialog;
import cloudspace.vm.filesystem.CSPath;


public class ManageUsersController extends GenericComposer
{
    private CloudSpaceConfiguration config;

    @SuppressWarnings("unused")
    private Window manageUsersWindow;

    private Tabbox masterTabbox;

    private Listbox userList;

    private Listbox groupList;

    private Component userDetailPane;

    private Label usernameLabel;

    private Button changePasswordButton;

    private Listbox memberOfGroupsListbox;

    private Listbox userPermissionsListbox;

    private Radiogroup authType;

    private Radio localAuth;

    private Radio remoteAuth;

    private Radiogroup userStatus;

    private Component groupDetailPane;

    private Label groupNameLabel;

    private Listbox groupMembersListbox;

    private Listbox groupPermissionsListbox;

    private Textbox initialUsernameField;

    private Textbox initialPassword1Field;

    private Textbox initialPassword2Field;

    private List<String> users;

    private List<GrantedAuthority> groups;

    private static final long serialVersionUID = -1797866708461045769L;

    private static final Logger log = Logger.getLogger( ManageUsersController.class );


    // ~ Methods ...............................................................

    public boolean isUserManaged()
    {
        String username = (String)userList.getSelectedItem().getValue();
        CloudSpaceUser user = UserRegistry.getInstance().getUser( username );
        return user.getAuthenticator().equals( UserRegistry.AUTHENTICATOR_LDAP );
    }


    // ----------------------------------------------------------
    @Override
    public void doAfterCompose( Component component ) throws Exception
    {
        super.doAfterCompose( component );

        config = CloudSpaceConfiguration.getInstance();

        manageUsersWindow = (Window)component;

        if ( config.isMultiUser() )
        {
            masterTabbox = (Tabbox)component.getFellow( "masterTabbox" );
            userList = (Listbox)component.getFellow( "userList" );
            // buildUserList();
            groupList = (Listbox)component.getFellow( "groupList" );

            userDetailPane = component.getFellow( "userDetailPane" );
            usernameLabel = (Label)component.getFellow( "usernameLabel" );
            changePasswordButton = (Button)component.getFellow( "changePasswordButton" );
            memberOfGroupsListbox = (Listbox)component.getFellow( "memberOfGroupsListbox" );
            userPermissionsListbox = (Listbox)component.getFellow( "userPermissionsListbox" );
            authType = (Radiogroup)component.getFellow( "authType" );
            localAuth = new Radio( "Local" );
            remoteAuth = new Radio( "Remote" );
            localAuth.setParent( authType );
            remoteAuth.setParent( authType );
            userStatus = (Radiogroup)component.getFellow( "userStatus" );

            groupNameLabel = (Label)component.getFellow( "groupNameLabel" );
            groupMembersListbox = (Listbox)component.getFellow( "groupMembersListbox" );
            groupPermissionsListbox = (Listbox)component.getFellow( "groupPermissionsListbox" );

            groupDetailPane = component.getFellow( "groupDetailPane" );
        }
        else
        {
            initialUsernameField = (Textbox)component.getFellow( "initialUsernameField" );
            initialPassword1Field = (Textbox)component.getFellow( "initialPassword1Field" );
            initialPassword2Field = (Textbox)component.getFellow( "initialPassword2Field" );
        }
    }


    // ----------------------------------------------------------
    public void onMasterSelectionChanged( Event event )
    {
        int selectedTab = masterTabbox.getSelectedIndex();

        if ( selectedTab == 0 && userList.getSelectedItem() != null )
        {
            switchToUserDetailPane();
        }
        else if ( selectedTab == 1 && groupList.getSelectedItem() != null )
        {
            switchToGroupDetailPane();
        }
        else
        {
            userDetailPane.setVisible( false );
            groupDetailPane.setVisible( false );
        }
    }


    public void onPasswordChange()
    {
        String username = (String)userList.getSelectedItem().getValue();
        String newPassword = Dialogs.passwordResetPrompt();
        if ( newPassword != null )
        {
            UserRegistry.getInstance().changePassword( username, newPassword );
        }

    }


    // ----------------------------------------------------------
    @SuppressWarnings("unchecked")
    private void switchToUserDetailPane()
    {
        String username = (String)userList.getSelectedItem().getValue();

        usernameLabel.setValue( username );
        CloudSpaceUser user = UserRegistry.getInstance().getUser( username );
        if ( user.isEnabled() )
        {
            userStatus.setSelectedItem( (Radio)userStatus.getFellow( "enable" ) );
        }
        else
        {
            userStatus.setSelectedItem( (Radio)userStatus.getFellow( "disable" ) );
        }

        if ( !user.getAuthenticator().equals( UserRegistry.AUTHENTICATOR_LOCAL ) )
        {
            authType.setSelectedItem( remoteAuth );
            changePasswordButton.setDisabled( true );
        }
        else
        {
            authType.setSelectedItem( localAuth );
            changePasswordButton.setDisabled( false );
        }
        memberOfGroupsListbox.getItems().clear();

        List<GrantedAuthority> groups = PermissionsManager.getInstance()
            .getGroupList();

        for ( GrantedAuthority group : groups )
        {
            boolean isMember = PermissionsManager.getInstance()
                .isUserInGroup( username, group );

            Listitem item = new Listitem();

            Listcell checkCell = new Listcell();
            item.appendChild( checkCell );

            Checkbox checkbox = new Checkbox();
            checkbox.setName( "membership_" + group.getAuthority() );
            checkbox.setChecked( isMember );

            if ( group.equals( GroupFactory.ADMIN_GROUP ) && isMember
                && username.equals( "admin" ) )
            {
                // Don't allow an admin to remove himself from the admin group.
                checkbox.setDisabled( true );
            }

            checkbox.addEventListener( "onCheck", groupMembershipEventListener );
            checkCell.appendChild( checkbox );

            Listcell labelCell = new Listcell();
            labelCell.setLabel( group.getAuthority() );
            item.appendChild( labelCell );

            memberOfGroupsListbox.getItems().add( item );
        }

        userPermissionsListbox.getItems().clear();

        Map<CSPath, PermissionToken> permissions = PermissionsManager.getInstance()
            .getUserPermissions( username );

        for ( CSPath path : permissions.keySet() )
        {
            PermissionToken permission = permissions.get( path );

            Listitem item = new Listitem();
            item.setValue( permission );

            Listcell pathCell = new Listcell();
            pathCell.setLabel( path.getQualifiedPath() );
            pathCell.setValue( path );
            item.appendChild( pathCell );

            Listcell readCell = new Listcell();
            item.appendChild( readCell );

            Checkbox checkbox = new Checkbox();
            checkbox.setName( "read_" + path );
            checkbox.setChecked( permission.allowsRead() );
            checkbox.addEventListener( "onCheck", permissionEventListener );
            readCell.appendChild( checkbox );

            Listcell writeCell = new Listcell();
            item.appendChild( writeCell );

            checkbox = new Checkbox();
            checkbox.setName( "write_" + path );
            checkbox.setChecked( permission.allowsWrite() );
            checkbox.addEventListener( "onCheck", permissionEventListener );
            writeCell.appendChild( checkbox );

            userPermissionsListbox.getItems().add( item );
        }

        userDetailPane.setVisible( true );
        groupDetailPane.setVisible( false );
    }


    // ----------------------------------------------------------
    @SuppressWarnings("unchecked")
    private void switchToGroupDetailPane()
    {
        GrantedAuthority group = (GrantedAuthority)groupList.getSelectedItem()
            .getValue();

        groupNameLabel.setValue( group.getAuthority() );

        groupMembersListbox.getItems().clear();

        List<String> members = PermissionsManager.getInstance()
            .getGroupMembers( group );

        for ( String member : members )
        {
            Listitem item = new Listitem();
            item.setLabel( member );

            groupMembersListbox.getItems().add( item );
        }

        groupPermissionsListbox.getItems().clear();

        Map<CSPath, PermissionToken> permissions = PermissionsManager.getInstance()
            .getGroupPermissions( group );

        for ( CSPath path : permissions.keySet() )
        {
            PermissionToken permission = permissions.get( path );

            Listitem item = new Listitem();
            item.setValue( permission );

            Listcell pathCell = new Listcell();
            pathCell.setLabel( path.getQualifiedPath() );
            item.appendChild( pathCell );

            Listcell readCell = new Listcell();
            item.appendChild( readCell );

            Checkbox checkbox = new Checkbox();
            checkbox.setName( "read_" + path );
            checkbox.setChecked( permission.allowsRead() );
            checkbox.addEventListener( "onCheck", permissionEventListener );
            readCell.appendChild( checkbox );

            Listcell writeCell = new Listcell();
            item.appendChild( writeCell );

            checkbox = new Checkbox();
            checkbox.setName( "write_" + path );
            checkbox.setChecked( permission.allowsWrite() );
            checkbox.addEventListener( "onCheck", permissionEventListener );
            writeCell.appendChild( checkbox );

            groupPermissionsListbox.getItems().add( item );
        }

        userDetailPane.setVisible( false );
        groupDetailPane.setVisible( true );
    }


    @SuppressWarnings("unchecked")
    public void onFilteringUsers( Event event )
    {
        filterList( userList.getChildren(), event );
    }


    @SuppressWarnings("unchecked")
    public void onFilteringGroups( Event event )
    {
        filterList( groupList.getChildren(), event );
    }


    private void filterList( List<Object> filterList, Event event )
    {
        InputEvent iEvent = (InputEvent)( (ForwardEvent)event ).getOrigin();
        String textboxValue = iEvent.getValue();
        for ( Object userObj : filterList )
        {
            if ( userObj instanceof Listhead )
            {
                continue;
            }
            Listitem user = (Listitem)userObj;
            String userName = (String)user.getLabel();
            if ( userName.startsWith( textboxValue ) )
            {
                user.setVisible( true );
            }
            else
            {
                user.setVisible( false );
            }
        }
    }


    public void onChangeAuthType( Event event )
    {
        // CheckEvent checkE = (CheckEvent) event;
        Radio selection = authType.getSelectedItem();
        String username = (String)userList.getSelectedItem().getValue();
        if ( selection.equals( localAuth ) )
        {
            UserRegistry.getInstance().changeAuthType( username,
                UserRegistry.AUTHENTICATOR_LOCAL );
            // UserRegistry.getInstance().setEnabled(username, false);
            // userStatus.setSelectedItem((Radio)userStatus.getFellow("disable"));
        }
        else
        {
            UserRegistry.getInstance().changeAuthType( username,
                UserRegistry.AUTHENTICATOR_LDAP );
        }
        switchToUserDetailPane();

    }


    public void onChangeEnable( Event event )
    {
        Radio selection = userStatus.getSelectedItem();
        String username = (String)userList.getSelectedItem().getValue();
        if ( selection.equals( userStatus.getFellow( "enable" ) ) )
        {
            UserRegistry.getInstance().setEnabled( username, true );
        }
        else
        {
            UserRegistry.getInstance().setEnabled( username, false );
        }
        // switchToUserDetailPane();
    }


    // ----------------------------------------------------------
    /**
     * Called when the "+" button in the user panel is clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onAddUserClicked( Event event )
    {
        Window dialog = (Window)Executions.createComponents( "/partials/dialogs/newUserPrompt.zul",
            null,
            null );
        NewUserDialog composerDialog = (NewUserDialog)dialog.getAttribute( "composer" );

        try
        {
            dialog.doModal();
        }
        catch ( SuspendNotAllowedException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch ( InterruptedException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        CSPath workspaceLoc = composerDialog.getResult();
        String userName = composerDialog.getUserName();
        if ( workspaceLoc != null && !userName.isEmpty() )
        {
            UserRegistry.getInstance().createUser( userName,
                "",
                workspaceLoc,
                UserRegistry.AUTHENTICATOR_LOCAL );
            users.add( userName );
            refreshUserList( userName );
        }
    }


    // ----------------------------------------------------------
    /**
     * Called when the Upload Roll button in the user panel is clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onUploadRollClicked( Event event )
    {
        Media media = null;

        try
        {
            media = Fileupload.get( "Select the CSV file that you wish to upload.",
                "Upload Multiple Users" );
        }
        catch ( InterruptedException e )
        {
            log.error( "An exception occurred while displaying the CSV upload "
                + "dialog", e );
        }

        if ( media != null )
        {
            Map<String, Object> args = new HashMap<String, Object>();
            args.put( "csvMedia", media );

            Window dialog = (Window)Executions.createComponents( "/partials/controlpanel/uploadRollDialog.zul",
                null,
                args );

            try
            {
                dialog.doModal();
            }
            catch ( Exception e )
            {
                log.error( "An exception occurred when displaying the modal "
                    + "upload users dialog", e );
                dialog.detach();
            }

            refreshGroupList( null );
            refreshUserList( null );
        }
    }


    // ----------------------------------------------------------
    /**
     * Called when the "-" button in the user panel is clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onDeleteUserClicked( Event event )
    {
        if ( userList.getSelectedItem() != null )
        {
            String user = (String)userList.getSelectedItem().getValue();
            if ( user.equals( "admin" ) )
            {
                // FIXME: Dont just return! Say something to the user
                return;
            }
            users.remove( user );
            UserRegistry.getInstance().deleteUser( user );
        }
        refreshUserList( null );
    }


    // ----------------------------------------------------------
    /**
     * Called when the "+" button in the group panel is clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onAddGroupClicked( Event event )
    {
        EditableListitem newItem = new EditableListitem( groupList );
        newItem.setEditListener( new InlineEditListener()
        {
            @Override
            public void accept( String text )
            {
                GrantedAuthority group = GroupFactory.groupWithName( text );

                PermissionsManager.getInstance().addGroup( group );
                refreshGroupList( group );
            }
        } );
    }


    // ----------------------------------------------------------
    /**
     * Called when the "-" button in the group panel is clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onDeleteGroupClicked( Event event )
    {
        if ( groupList.getSelectedItem() != null )
        {
            GrantedAuthority group = (GrantedAuthority)groupList.getSelectedItem()
                .getValue();
            PermissionsManager.getInstance().deleteGroup( group );
            updateGroupList( null );
            userDetailPane.setVisible( false );
            groupDetailPane.setVisible( false );
        }
    }


    // ----------------------------------------------------------
    /**
     * Called when the "+" button under the directory permissions list is
     * clicked.
     * 
     * @param event
     *            the ZK event
     */
    @SuppressWarnings("unchecked")
    public void onAddUserPermissionClicked( Event event )
    {
        final String username = (String)userList.getSelectedItem().getValue();

        final Listitem newItem = new Listitem();
        Listcell cell = new Listcell();
        cell.setParent( newItem );

        userPermissionsListbox.getItems().add( newItem );

        InlineEditor.attachToElement( cell, new InlineEditListener()
        {
            @Override
            public void accept( String text )
            {
                PermissionsManager.getInstance()
                    .addDirectoryPermission( new CSPath( text ),
                        new UserPermissionToken( username, "r" ) );

                // Easy way to refresh.
                switchToUserDetailPane();
            }


            @Override
            public void decline()
            {
                userPermissionsListbox.getItems().remove( newItem );
            }
        } );
    }


    // ----------------------------------------------------------
    /**
     * Called when the "+" button under the directory permissions list is
     * clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onDeleteUserPermissionClicked( Event event )
    {
        Listitem selectedItem = userPermissionsListbox.getSelectedItem();

        if ( selectedItem == null )
        {
            return;
        }

        Listcell pathCell = (Listcell)selectedItem.getFirstChild();
        CSPath path = (CSPath)pathCell.getValue();

        UserPermissionToken token = (UserPermissionToken)selectedItem.getValue();
        PermissionsManager.getInstance().removeUserDirectoryPermission( path,
            token.getUsername() );

        userPermissionsListbox.getItems().remove( selectedItem );
    }


    // ----------------------------------------------------------
    /**
     * Called when the "+" button under the directory permissions list is
     * clicked.
     * 
     * @param event
     *            the ZK event
     */
    @SuppressWarnings("unchecked")
    public void onAddGroupPermissionClicked( Event event )
    {
        final GrantedAuthority group = (GrantedAuthority)groupList.getSelectedItem()
            .getValue();

        final Listitem newItem = new Listitem();
        Listcell cell = new Listcell();
        cell.setParent( newItem );

        groupPermissionsListbox.getItems().add( newItem );

        InlineEditor.attachToElement( cell, new InlineEditListener()
        {
            @Override
            public void accept( String text )
            {
                PermissionsManager.getInstance()
                    .addDirectoryPermission( new CSPath( text ),
                        new GroupPermissionToken( group, "r" ) );

                // Easy way to refresh.
                switchToGroupDetailPane();
            }


            @Override
            public void decline()
            {
                userPermissionsListbox.getItems().remove( newItem );
            }
        } );
    }


    // ----------------------------------------------------------
    /**
     * Called when the "+" button under the directory permissions list is
     * clicked.
     * 
     * @param event
     *            the ZK event
     */
    public void onDeleteGroupPermissionClicked( Event event )
    {
        Listitem selectedItem = groupPermissionsListbox.getSelectedItem();

        if ( selectedItem == null )
        {
            return;
        }

        Listcell pathCell = (Listcell)selectedItem.getFirstChild();
        CSPath path = (CSPath)pathCell.getValue();

        GroupPermissionToken token = (GroupPermissionToken)selectedItem.getValue();
        PermissionsManager.getInstance().removeGroupDirectoryPermission( path,
            token.getGroup() );

        groupPermissionsListbox.getItems().remove( selectedItem );
    }


    // ----------------------------------------------------------
    public void onCreateInitialUser( Event event )
    {
        String username = initialUsernameField.getValue();
        String password1 = initialPassword1Field.getValue();
        String password2 = initialPassword2Field.getValue();

        if ( !password1.equals( password2 ) )
        {
            try
            {
                Messagebox.show( "The passwords do not match." );
            }
            catch ( InterruptedException e )
            {
                // Do nothing.
            }

            return;
        }

        UserRegistry.getInstance().createUser( username,
            password1,
            null,
            UserRegistry.AUTHENTICATOR_LOCAL );

        GrantedAuthority adminGroup = GroupFactory.ADMIN_GROUP;
        PermissionsManager.getInstance().addGroup( adminGroup );
        PermissionsManager.getInstance().addUserToGroup( username, adminGroup );

        try
        {
            Messagebox.show( "The user \"" + username + "\" has been created "
                + "and granted administrative access on CloudSpace. Click "
                + "OK to return to the CloudSpace home page where you can"
                + "log in." );
        }
        catch ( InterruptedException e )
        {
            // Do nothing.
        }

        // Force the entire control panel to reload.
        Executions.sendRedirect( "/" );
    }


    // ----------------------------------------------------------
    public List<String> getUsers()
    {
        if ( users == null )
        {
            users = UserRegistry.getInstance().getUserList();
        }

        return users;
    }


    // ----------------------------------------------------------
    public List<GrantedAuthority> getGroups()
    {
        if ( groups == null )
        {
            groups = PermissionsManager.getInstance().getGroupList();
        }

        return groups;
    }


    // ----------------------------------------------------------
    @SuppressWarnings("unchecked")
    private void refreshUserList( String selected )
    {
        // Listitem selectedItem = userList.getSelectedItem();

        // buildUserList();
        // userList.setSelectedItem(selectedItem);

        userList.getItems().clear();
        for ( String user : users )
        {
            Listitem item = new Listitem();
            item.setLabel( user );
            item.setValue( user );
            userList.getItems().add( item );

            if ( user.equals( selected ) )
            {
                userList.selectItem( item );
            }
        }
        if ( selected == null )
        {
            userDetailPane.setVisible( false );
        }
        else
        {
            switchToUserDetailPane();
        }
    }


    // ----------------------------------------------------------
    private void refreshGroupList( GrantedAuthority selected )
    {
        updateGroupList( selected );
        if ( selected != null )
            switchToGroupDetailPane();
    }


    @SuppressWarnings("unchecked")
    private void updateGroupList( GrantedAuthority selected )
    {
        if ( selected == null && groupList.getSelectedItem() != null )
        {
            selected = (GrantedAuthority)groupList.getSelectedItem().getValue();
        }

        groups = PermissionsManager.getInstance().getGroupList();
        groupList.getItems().clear();

        for ( GrantedAuthority group : groups )
        {
            Listitem item = new Listitem();
            item.setLabel( group.toString() );
            item.setValue( group );
            groupList.getItems().add( item );

            if ( group.equals( selected ) )
            {
                groupList.selectItem( item );
            }
        }
    }

    // ~ Private classes .......................................................

    // ----------------------------------------------------------
    private EventListener groupMembershipEventListener = new EventListener()
    {
        public void onEvent( Event paramEvent ) throws Exception
        {
            String username = (String)userList.getSelectedItem().getValue();
            Checkbox checkbox = (Checkbox)paramEvent.getTarget();
            String groupName = checkbox.getName()
                .substring( "membership_".length() );
            GrantedAuthority group = GroupFactory.groupWithName( groupName );

            if ( checkbox.isChecked() )
            {
                PermissionsManager.getInstance().addUserToGroup( username,
                    group );
            }
            else
            {
                PermissionsManager.getInstance().removeUserFromGroup( username,
                    group );
            }
        }
    };

    // ----------------------------------------------------------
    private EventListener permissionEventListener = new EventListener()
    {
        public void onEvent( Event paramEvent ) throws Exception
        {
            Checkbox checkbox = (Checkbox)paramEvent.getTarget();
            Listitem listItem = (Listitem)checkbox.getParent().getParent();
            PermissionToken token = (PermissionToken)listItem.getValue();
            String checkName = checkbox.getName();

            if ( checkName.startsWith( "read_" ) )
            {
                token.setAllowsRead( checkbox.isChecked() );
            }
            else
            {
                token.setAllowsWrite( checkbox.isChecked() );
            }
        }
    };
}
